import { Component, ViewChild } from '@angular/core';
import { NavController, AlertController, ToastController, Nav, NavParams, Slides } from 'ionic-angular';
import { RestService } from '../../app/services/rest.service';
import { TranslateService } from '@ngx-translate/core';
// import { AlarmPage } from '../alarm/alarm';

// import * as echarts from 'echarts';
import * as _ from 'lodash';

@Component({
  selector: 'page-report',
  templateUrl: 'report.html'
})
export class ReportPage {
  @ViewChild(Slides) slides: Slides;
  fDate: any;
  tDate: any;
  fDateStr: any;
  tDateStr: any;

  person: any;
  persons: any;

  moveTotal = '-';
  breatheAlarmTotal = '-';
  heartAlarmTotal = '-';
  awayAlarmTotal = '-';
  wetAlarmTotal = '-';

  heart = '-';
  breathe = '-';
  sleepScore = 0;
  sleepAdjustment = '';
  sleepDisplay: any;

  DEEP_SLEEP_MODE = "2";
  SHALLOW_SLEEP_MODE = "1";
  deepSleep = 0;
  shallowSleep = 0;
  totalSleep = 0;

  // interval;
  options: any;

  bChartOptions;
  bEchartsInstance;

  hChartOptions;
  hEchartsInstance;

  moveChartOptions;
  moveChartsInstance;
  moveTitle;

  awayAlarmChartOptions;
  awayAlarmChartsInstance;

  sideAlarmChartOptions;
  sideAlarmChartsInstance;

  upAlarmChartOptions;
  upAlarmChartsInstance;

  breatheAlarmChartOptions;
  breatheAlarmChartsInstance;

  heartAlarmChartOptions;
  heartAlarmChartsInstance;

  wetAlarmChartOptions;
  wetAlarmChartsInstance;

  turnOverAlarmChartOptions;
  turnOverAlarmChartsInstance;

  sleepChartOptions;
  sleepChartsInstance;

  constructor(private rest: RestService,
    private toastCtrl: ToastController,
    private translate: TranslateService,
    public alertCtrl: AlertController,
    public nav: Nav,
    public navParams: NavParams,
    public navCtrl: NavController) {
    this.person = navParams.data;
    this.persons = navParams.data;

    this.moveTitle = this.translate.get('moveTitle')['value'];
    this.options = {
      title: {
        text: '',
        subtext: '',
        subtextStyle: { color: 'black' },
        x: 'center',
        y: 'top',
        textStyle: {
          color: 'darkblue'
        },
      },
      tooltip: {
        trigger: 'axis',
      },
      grid: {
        x: '15px',
        y: '10px',
        x2: '18px',
        y2: '10px',
        containLabel: true
      },
      xAxis: {
        type: 'time',
        splitLine: {
          show: true
        }
      },
      yAxis: {
        type: 'value',
        boundaryGap: false,
        splitLine: {
          show: true
        }
      },
      series: [{
        type: 'scatter',
        showSymbol: false,
        markLine: {
          itemStyle: {
            normal: {
              lineStyle: {
                type: 'dashed',
                color: 'darkred'
              }
            }
          },
          data: []
        },
        data: []
      }]
    };
    this.fDate = new Date().getTime() - 86400000 + 8*60*60*1000;
    this.tDate = new Date().getTime() - 86400000 + 8*60*60*1000;
    this.fDateStr = new Date(this.fDate).toISOString();
    this.tDateStr = new Date(this.tDate).toISOString();
    this.initChart();
  }

  initChart() {
    const bSubtext = this.translate.get('heartUnit')['value'];
    this.bChartOptions = _.cloneDeep(this.options);
    this.bChartOptions.series[0].markLine.data = [
      { name: 'upper', yAxis: this.person.breatheUp },
      { name: 'lower', yAxis: this.person.breatheLow },
    ];
    this.bChartOptions.title.text = this.translate.get('breathe')['value'] + " (" + bSubtext + ")";
    this.bChartOptions.grid.y = '30px';
    this.bChartOptions.series[0].type = 'line';
    this.bChartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + bSubtext;
    };

    this.hChartOptions = _.cloneDeep(this.options);
    this.hChartOptions.series[0].markLine.data = [
      { name: 'upper', yAxis: this.person.heartUp },
      { name: 'lower', yAxis: this.person.heartLow },
    ];
    this.hChartOptions.title.text = this.translate.get('heart')['value'] + " (" + bSubtext + ")";
    this.hChartOptions.grid.y = '30px';
    this.hChartOptions.series[0].type = 'line';
    this.hChartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + bSubtext;
    };

    this.moveChartOptions = _.cloneDeep(this.options);
    this.moveChartOptions.title.text = this.translate.get('MOVE')['value'];
    this.moveChartOptions.grid.y = '30px';
    this.moveChartOptions.series[0].type = 'bar';
    this.moveChartOptions.series[0].barWidth = '12px';
    this.moveChartOptions.series[0].itemStyle = {
      normal: {
        color: params => {
          let value = params.data[1];
          if (value < 5) {
            return 'green';
          } else if (value >= 5 && value <= 10) {
            return 'blue';
          } else if (value > 10 && value <= 15) {
            return 'orange';
          } else {
            return 'red';
          }
        }
      }
    };

    this.moveChartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + this.translate.get('moveUnit')['value'];
    };
    // this.moveChartOptions.series[0].markLine.data = [{ yAxis: this.person.move }];

    this.awayAlarmChartOptions = _.cloneDeep(this.options);
    this.awayAlarmChartOptions.title.text = this.translate.get('awayAlarm')['value'];
    this.awayAlarmChartOptions.grid.y = '30px';
    this.awayAlarmChartOptions.series[0].type = 'bar';
    this.awayAlarmChartOptions.series[0].barWidth = '12px';
    this.awayAlarmChartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + this.translate.get('moveUnit')['value'];
    };

    this.breatheAlarmChartOptions = _.cloneDeep(this.options);
    this.breatheAlarmChartOptions.title.text = this.translate.get('breatheAlarm')['value'];
    this.breatheAlarmChartOptions.grid.y = '30px';
    this.breatheAlarmChartOptions.series[0].type = 'line';
    this.breatheAlarmChartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + this.translate.get('heartUnit')['value'];
    };

    this.heartAlarmChartOptions = _.cloneDeep(this.options);
    this.heartAlarmChartOptions.title.text = this.translate.get('heartAlarm')['value'];
    this.heartAlarmChartOptions.grid.y = '30px';
    this.heartAlarmChartOptions.series[0].type = 'line';
    this.heartAlarmChartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + this.translate.get('heartUnit')['value'];
    };

    this.wetAlarmChartOptions = _.cloneDeep(this.options);
    this.wetAlarmChartOptions.title.text = this.translate.get('wetAlarm')['value'];
    this.wetAlarmChartOptions.grid.y = '30px';
    this.wetAlarmChartOptions.series[0].type = 'bar';
    this.wetAlarmChartOptions.series[0].barWidth = '12px';
    this.wetAlarmChartOptions.tooltip.formatter = (params) => {
      return new Date(params[0].data[0]).toLocaleString() + '<br>' + params[0].data[1] + ' ' + this.translate.get('moveUnit')['value'];
    };
  }

  onBChartInit(ec) {
    this.bEchartsInstance = ec;
    ec.setOption(this.bChartOptions);
  }

  onHChartInit(ec) {
    this.hEchartsInstance = ec;
    ec.setOption(this.hChartOptions);
  }

  onMoveChartInit(ec) {
    this.moveChartsInstance = ec;
    this.moveChartsInstance.setOption(this.moveChartOptions);
  }

  onAwayAlarmChartInit(ec) {
    this.awayAlarmChartsInstance = ec;
    this.awayAlarmChartsInstance.setOption(this.awayAlarmChartOptions);
  }

  onSideAlarmChartInit(ec) {
    this.sideAlarmChartsInstance = ec;
    this.sideAlarmChartsInstance.setOption(this.sideAlarmChartOptions);
  }

  onUpAlarmChartInit(ec) {
    this.upAlarmChartsInstance = ec;
    this.upAlarmChartsInstance.setOption(this.upAlarmChartOptions);
  }

  onBreatheAlarmChartInit(ec) {
    this.breatheAlarmChartsInstance = ec;
    this.breatheAlarmChartsInstance.setOption(this.breatheAlarmChartOptions);
  }

  onHeartAlarmChartInit(ec) {
    this.heartAlarmChartsInstance = ec;
    this.heartAlarmChartsInstance.setOption(this.heartAlarmChartOptions);
  }

  onWetAlarmChartInit(ec) {
    this.wetAlarmChartsInstance = ec;
    this.wetAlarmChartsInstance.setOption(this.wetAlarmChartOptions);
  }

  onTurnOverAlarmChartInit(ec) {
    this.turnOverAlarmChartsInstance = ec;
    this.turnOverAlarmChartsInstance.setOption(this.turnOverAlarmChartOptions);
  }

  onSleepChartInit(ec) {
    this.sleepChartsInstance = ec;
    this.sleepChartsInstance.setOption(this.sleepChartOptions);
  }

  resetChartOptions() {
    if (this.bEchartsInstance) {
      this.bEchartsInstance.setOption(this.bChartOptions);
    }

    if (this.hEchartsInstance) {
      this.hEchartsInstance.setOption(this.bChartOptions);
    }

    if (this.moveChartsInstance) {
      this.moveChartsInstance.setOption(this.bChartOptions);
    }
  }

  processType(startTime, endTime, alarm, chartInstance, chartOptions) {
    const type = this.rest.getAlarmEnumNumber(alarm);

    this.rest.getWithParams('/api/elastic/typeInRange', {
      personId: this.person.id,
      startTime: startTime,
      endTime: endTime,
      type: type
    }).subscribe(resp => {
      let data: any = resp;
      if (data && data.length > 0) {
        if (data[0][0] !== startTime * 1000) {
          data.unshift([startTime * 1000, '']);
        }

        if (data[data.length - 1][0] !== endTime * 1000) {
          data.push([endTime * 1000, '']);
        }
      } else {
        data = this.buildEmptyData(startTime, endTime);
      }

      chartOptions.series[0].data = data;
      chartInstance.setOption(chartOptions);
      chartInstance.resize();
    });
  }


  initData() {
    // person status
    this.rest.get('/data/person/' + this.person.id).subscribe(data => {
      this.person = data;
    });

    let currentTime = new Date().getTime();
    if (Date.parse(this.tDateStr) > currentTime + 86400000) {
      this.showToast(this.translate.get('endTimeGreaterThanCurTime')['value']);
      return;
    }

    if (Date.parse(this.tDateStr) < Date.parse(this.fDateStr)) {
      this.showToast(this.translate.get('startTimeGreaterThanEndTime')['value']);
      return;
    }

    this.fDateStr = this.fDateStr.substr(0, 11) + "00:00:00.000Z";
    this.tDateStr = this.tDateStr.substr(0, 11) + "23:59:59.999Z";
    const startTime = Math.round(Date.parse(this.fDateStr) / 1000) - 8 * 60 * 60;
    const endTime = Math.round(Date.parse(this.tDateStr) / 1000) - 8 * 60 * 60;
    // const step = 100;

    // breathe
    this.processType(startTime, endTime, 'HIST_HEART', this.hEchartsInstance, this.hChartOptions);
    this.processType(startTime, endTime, 'HIST_BREATHE', this.bEchartsInstance, this.bChartOptions);
    this.processType(startTime, endTime, 'HIST_MOVE', this.moveChartsInstance, this.moveChartOptions);
    this.processType(startTime, endTime, 'AWAY', this.awayAlarmChartsInstance, this.awayAlarmChartOptions);
    this.processType(startTime, endTime, 'BREATHE', this.breatheAlarmChartsInstance, this.breatheAlarmChartOptions);
    this.processType(startTime, endTime, 'HEART', this.heartAlarmChartsInstance, this.heartAlarmChartOptions);
    this.processType(startTime, endTime, 'WET', this.wetAlarmChartsInstance, this.wetAlarmChartOptions);
    // sleep
    /*
    const sleepIntervals = this.getSleepIntervals();
    const sleepStep = 30;
    this.rest.getWithParams('/api/pro/counterRange', {
      counter: 'sleep',
      personId: this.person.id,
      startTime: sleepIntervals[0],
      endTime: sleepIntervals[1],
      step: sleepStep
    }).subscribe(resp => {
      if (!resp || !_.isArray(resp) || resp.length < 1) {
        this.deepSleep = 0;
        this.shallowSleep = 0;
        return;
      }

      this.deepSleep = 0;
      this.shallowSleep = 0;
      const data = resp;
      data.forEach(item => {
        if (item[1] === this.DEEP_SLEEP_MODE) {
          this.deepSleep++;
        } else if (item[1] === this.SHALLOW_SLEEP_MODE) {
          this.shallowSleep++;
        }
      });
      this.deepSleep = Math.round(this.deepSleep * 100 / 120.0) / 100.0;
      this.shallowSleep = Math.round(this.shallowSleep * 100 / 120.0) / 100.0;
      this.totalSleep = Math.round((this.deepSleep + this.shallowSleep) * 100) / 100.0;
      this.sleepCalculation();
    });
    */
  }

  buildEmptyData(startTime, endTime) {
    const data = [[startTime * 1000, ''], [endTime * 1000, '']];
    return data;
  }

  /*
  sleepCalculation() {
    const total = this.deepSleep + this.shallowSleep;
    if (this.deepSleep <= 0.1) {
      // If deep sleep is less than 6 minutes (0.1 hours), treat it as bad data
      this.sleepScore = 0;
    } else {
      const ratio = (this.deepSleep * 100.0) / total;
      if (ratio < 12.5) {
        this.sleepScore = 0;
      } else if (ratio >= 12.5 && ratio < 20) {
        this.sleepScore = Math.round(50 + ((80 - 50) / (20.0 - 12.5)) * (ratio - 12.5));
      } else if (ratio >= 20 && ratio < 22) {
        this.sleepScore = Math.round(80 + ((90 - 80) / (22.0 - 20.0)) * (ratio - 20.0));
      } else if (ratio >= 22 && ratio < 23) {
        this.sleepScore = Math.round(90 + ((95 - 90) / (23.0 - 22.0)) * (ratio - 22.0));
      } else if (ratio >= 23 && ratio < 25) {
        this.sleepScore = Math.round(95 + ((100 - 95) / (25.0 - 23.0)) * (ratio - 23.0));
      } else if (ratio >= 25) {
        this.sleepScore = 100;
      }
    }

    this.sleepDisplay = this.sleepScore;
    if (this.sleepScore >= 100) {
      this.sleepAdjustment = 'sleepPerfect';
    } else if (this.sleepScore >= 95) {
      this.sleepAdjustment = 'sleepGood';
    } else if (this.sleepScore >= 85) {
      this.sleepAdjustment = 'sleepNormal';
    } else if (this.sleepScore >= 70) {
      this.sleepAdjustment = 'sleepFair';
    } else if (this.sleepScore >= 60) {
      this.sleepAdjustment = 'sleepPass';
    } else {
      this.sleepAdjustment = 'sleepBelow';
      this.sleepDisplay = '< 50';
    }
  }

  getSleepColor() {
    if (this.sleepScore >= 100) {
      return 'secondary';
    } else if (this.sleepScore >= 95) {
      return 'secondary';
    } else if (this.sleepScore >= 85) {
      return 'primary';
    } else if (this.sleepScore >= 70) {
      return 'primary';
    } else if (this.sleepScore >= 60) {
      return 'primary';
    } else {
      return 'danger';
    }
  }

  startRoutine() {
    if (this.interval) {
      clearInterval(this.interval);
    }

    this.initChart();
    this.resetChartOptions();
    this.initData();

    this.interval = setInterval(() => {
      this.initData();
    }, 5000);
  }

  getSecondsFromLast8Am() {
    let hour = new Date().getHours();
    hour = hour >= 8 ? (hour - 8) : (24 + hour - 8);
    return hour * 60 * 60 + new Date().getMinutes() * 60 + new Date().getSeconds() - 1;
  }

  getSleepIntervals() {
    const times = [];
    let hour = new Date().getHours();
    const currentTime = Math.round(new Date().getTime() / 1000);
    if (hour >= 20) {
      const pastSecondsFrom8Pm = (hour - 20) * 60 * 60 + new Date().getMinutes() * 60 + new Date().getSeconds();
      const endTime = currentTime;
      const startTime = endTime - pastSecondsFrom8Pm;
      times.push(startTime);
      times.push(endTime);
      return times;
    } else if (hour < 20 && hour >= 8) {
      const endTime = currentTime - this.getSecondsFromLast8Am();
      const startTime = endTime - 12 * 60 * 60;
      times.push(startTime);
      times.push(endTime);
      return times;
    } else if (hour < 8) {
      const pastSecondsFrom8Pm = (hour + 4) * 60 * 60 + new Date().getMinutes() * 60 + new Date().getSeconds();
      const endTime = currentTime;
      const startTime = endTime - pastSecondsFrom8Pm;
      times.push(startTime);
      times.push(endTime);
      return times;
    }
  }

  getBedImage() {
    if (this.person.awayAlarmFlag) {
      return "../../assets/imgs/leave.png";
    }

    if (this.person.upAlarmFlag) {
      return "../../assets/imgs/up.png";
    }

    if (this.person.sideAlarmFlag) {
      return "../../assets/imgs/side.png";
    }

    return "../../assets/imgs/sleep.png";
  }

  getBedAlarmStatus() {
    if (this.person.awayAlarm && this.person.awayAlarmFlag) {
      return 'danger';
    }

    if (this.person.upAlarm && this.person.upAlarmFlag) {
      return 'danger';
    }

    if (this.person.sideAlarm && this.person.sideAlarmFlag) {
      return 'danger';
    }

    return 'primary';
  }

  getBedAlarmString() {
    if (this.person.upAlarmFlag) {
      return this.translate.get('UP')['value'];
    } else if (this.person.sideAlarmFlag) {
      return this.translate.get('SIDE')['value'];
    } else if (this.person.awayAlarmFlag) {
      return this.translate.get('AWAY')['value'];
    } else {
      return this.translate.get('normal')['value'];
    }
  }

  getHeartAlarmStatus() {
    if (this.heart === '' || this.heart === '-') {
      return 'primary';
    }

    const currentValue = _.toNumber(this.heart);
    if (currentValue < this.person.heartLow || currentValue > this.person.heartUp) {
      return 'danger';
    }

    return 'primary';
  }

  getBreatheAlarmStatus() {
    if (this.breathe === '' || this.breathe === '-') {
      return 'primary';
    }

    const currentValue = _.toNumber(this.breathe);
    if (currentValue < this.person.breatheLow || currentValue > this.person.breatheUp) {
      return 'danger';
    }

    return 'primary';
  }

  getWetImage() {
    return this.person.wetAlarmFlag ? '../../assets/imgs/wet.png' : '../../assets/imgs/dry.png';
  }

  getWetAlarmStatus() {
    return this.person.wetAlarm && this.person.wetAlarmFlag ? 'danger' : 'primary';
  }

  getWetAlarmString() {
    return this.person.wetAlarmFlag ? this.translate.get('wet')['value'] : this.translate.get('dry')['value'];
  }

  nav2alarm(alarm) {
    this.navCtrl.push(AlarmPage, {
      person: this.person,
      alarm: alarm
    });
  }
  */

  ionViewCanEnter(): boolean {
    return true;
  }

  ionViewDidEnter() {
    // this.startRoutine();
    this.initData();
  }

  ionViewWillLeave() {
    /*
    if (this.interval) {
      clearInterval(this.interval);
    }
    */
  }

  showToast(message) {
    const toast = this.toastCtrl.create({
      message: message,
      duration: 3000,
      position: 'middle'
    });

    toast.present(toast);
  }

  navBack() {
    this.navCtrl.pop();
  }
}
